---
title: TitleCase
summary: API reference for TitleCase.
status: draft
owner: SAIF Doc Gen
last_reviewed: 2026-08-21
library: SAIF.Business.Utilities
reference_type: embedded
---

# TitleCase

A stateless, rules-driven text-casing engine that normalizes legacy uppercase-stored text into display-ready title case while preserving original delimiter characters. The class enforces a comprehensive set of recognition lists (acronyms, minor words, irregular spellings, ordinal suffixes) and applies deterministic per-token casing rules to produce consistently formatted names, addresses, and descriptions. All members are shared/static; the class holds no instance state, making it thread-safe and suitable for high-volume formatting workloads.

## Purpose
- Normalize free-form name/address/description text (typically all-caps legacy data) into display-ready title case by applying rules-driven per-token casing while preserving all original delimiter characters in their original positions.
- Enforce consistent casing for recognized acronyms (e.g. `LLC`, `PhD`, directionals, state codes), minor words (e.g. `is`, `the`, `of`), and irregular spellings (e.g. `LaCombe`).
- Support optional features like capital-letter padding (expanding run-together identifiers) and ordinal suffix normalization (e.g. `52nd`).

## Context
- Namespace: `SAIF.Business.Utilities`
- Assembly/package: `SAIF.Business.Utilities.dll`
- Base class: `System.Object`

## Public members

| Member | Signature | Purpose |
| --- | --- | --- |
| `ToTitleCase` | `Public Shared Function ToTitleCase(ByVal inString As String) As String` | Entry point for title-casing; sole public member of the class. Accepts a free-form string and returns the cased result. Applies all recognition lists and delimiter preservation. Returns input unchanged if `Nothing` or whitespace-only. |

## Private implementation members (documented for control flow)

The following members implement the title-casing logic and are not part of the public surface:

| Member | Signature | Role |
| --- | --- | --- |
| `UpperCaseWordList` | `Private Shared ReadOnly` array of `String` | Recognition list for acronyms and abbreviations (e.g. `SAIF`, `LLC`, `PhD`, state codes, roman numerals) — words matching this list are fully upper-cased |
| `LowerCaseWordList` | `Private Shared ReadOnly` array of `String` | Recognition list for minor words (e.g. `is`, `in`, `the`, `of`, `on`, `and`, `de`) — words matching this list are fully lower-cased (unless [BR-011](../../business-rules.md#br-011-first-character-override)) |
| `MixedCaseWordList` | `Private Shared ReadOnly` array of `String` | Recognition list for words requiring irregular mixed-case casing (e.g. `PhD`, `LaCombe`) — words matching this list (case-insensitive) are replaced with their canonical form |
| `MixedCasePrefixList` | `Private Shared ReadOnly` array of `String` | Recognition list for surname prefixes (`Mc`, `O'`) — handled specially to retain prefix casing and proper-case the remainder |
| `MixedCaseSuffixList` | `Private Shared ReadOnly` array of `String` | Recognition list for possessive/exact suffixes (`'s`, `'t`) — normalized to canonical lower-case form after reassembly |
| `NumberSuffixes` | `Private Shared ReadOnly` array of `String` | Recognition list for ordinal suffixes (`st`, `nd`, `rd`, `th`) — used to identify and lowercase numeric ordinal tokens |
| `TitleCaseSingleWord` | `Private Shared Function (ByVal word As String) As String` | Apply casing rules to a single token; implements the rule-precedence chain ([BR-004](../../business-rules.md#br-004-preformatted-mixed-case) through [BR-009](../../business-rules.md#br-009-default-proper-casing) then [BR-012](../../business-rules.md#br-012-surname-prefixes)) |
| `ReassembleString` (overload 1) | `Private Shared Function (ByVal splitWords As String(), ByVal inSourceString As String) As String` | Rebuild the cased string with delimiter characters at their original positions; entry point for recursion |
| `ReassembleString` (overload 2) | `Private Shared Function (ByVal splitWords As String(), ByVal inSourceString As String, ByVal currentWordIndex As Integer, ByVal currentCharIndex As Integer, ByVal result As StringBuilder) As String` | Recursive helper that walks through source character positions, inserting delimiters and cased word tokens |
| `ApplyExactSuffixList` | `Private Shared Function (ByVal inWord As String) As String` | Normalize trailing suffixes (e.g. `'s`) to canonical casing using `MixedCaseSuffixList` |
| `HasNumberSuffix` | `Private Shared Function (ByVal inWord As String) As Boolean` | Guard: return true if the word ends with a recognized ordinal suffix and the preceding portion is purely numeric |
| `GetNumberSuffixParts` | `Private Shared Function (ByVal inWord As String) As Tuple(Of String, String)` | Decompose an ordinal token into numeric and suffix parts |
| `ContainsOnlyNumericCharacters` | `Public Function (ByVal Target As String) As Boolean` | **Note: This is exposed as a public extension method via `TitleCaseExtensions`** — Guard for ordinal suffix detection; confirms a token is purely digits (non-null, non-blank, no `\D` match) |

## Behavioral notes
- **Statelessness**: All members are `Shared`; the class holds no instance state, so calls are side-effect free and thread-safe*.
- **Recursion in reassembly**: `ReassembleString` is recursive; recursion depth scales with word count. For heavily-delimited strings (e.g. file paths with many slashes), deep recursion is possible*.
- **Delimiter position mapping**: The reassembly algorithm assumes an exact correspondence between split-word count and delimiter positions in the source string. Malformed input whose delimiter pattern is not perfectly reconstructible can cause `IndexOutOfRangeException`**.
- **Rule precedence within `TitleCaseSingleWord`**: The per-word casing rules are applied in strict order — [BR-004](../../business-rules.md#br-004-preformatted-mixed-case), [BR-005](../../business-rules.md#br-005-acronyms-and-abbreviations), [BR-006](../../business-rules.md#br-006-minor-words), [BR-007](../../business-rules.md#br-007-irregular-mixed-case-spelling), [BR-008](../../business-rules.md#br-008-ordinal-suffix-normalization), [BR-009](../../business-rules.md#br-009-default-proper-casing), then [BR-012](../../business-rules.md#br-012-surname-prefixes) as a post-adjustment. The first matching branch wins; subsequent branches are never evaluated*.
- **First-character override**: [BR-011](../../business-rules.md#br-011-first-character-override) forces the first character of the final result to upper case, even if it matches a minor-word rule.
- **`StrConv` usage**: The `ToProperCase` extension method (exposed via `TitleCaseExtensions`) uses VB.NET's `StrConv(..., VbStrConv.ProperCase)` as a fallback when no specific rule matches. This VB runtime function may behave differently across frameworks and locales*.

## Constraints and usage notes
- The public `ToTitleCase` method is stateless and can be called concurrently without synchronization.
- Input strings with multi-byte or accented characters are handled by the regex and string routines; whether behavior matches intent for non-ASCII scripts is unverified*.
- The regex pattern `[^\d\w]` (used for splitting) includes underscores as word characters (`\w` in .NET includes `[a-zA-Z0-9_]`); strings with underscores will not be split on underscore characters, so `Policy_Name` remains a single token*.
- Recognition lists are hard-coded and immutable; adding a new acronym or exception requires a code change and redeploy, not a configuration change.

## Related documentation
- [Index](../index.md)
- [TitleCaseExtensions](TitleCaseExtensions.md)
- [mdlTextConversion](mdlTextConversion.md)
- [Architecture](../../architecture.md)
- [Dependencies](../../dependencies.md)
- [Operations and processes](../../operations-processes.md)
- [Business rules](../../business-rules.md)

> **Note:** Statements marked with * were inferred from code structure, naming conventions, or contextual evidence where direct confirmation was not available in source artifacts. Statements marked with ** could not be confirmed; treat as unknown until verified.

## Sources
- `SAIF.Business.Utilities/TitleCase.vb`
- `SAIF.Business.Utilities/SAIF.Business.Utilities.vbproj`
